
'use client';
import { useState, useEffect } from 'react'
import { ApiPromise, WsProvider, Keyring } from '@polkadot/api'
import { atom, useAtom, useSetAtom, useAtomValue } from 'jotai'
import { atomWithReset, RESET } from 'jotai/utils'
import { custom, createWalletClient } from 'viem'
import { mainnet } from 'viem/chains'
import dedent from 'dedent'
import { CheckCircleIcon, ExclamationCircleIcon, ArrowPathIcon, LightBulbIcon, ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
import { getMappingAccount, signAndSend, signAndSendEvm, signMessage } from 'evm-account-mapping-sdk'
const formatter = new Intl.NumberFormat('en-US')
import copy from "copy-to-clipboard";

let api = null, walletClient;

export function Main() {
    const [rpcEndpoint, setRpcEndpoint] = useState("wss://testnet-rpc1.cess.cloud/ws/");
    const [toAddress, setToAddress] = useState("");
    const [okTipsTxt, setOkTipsTxt] = useState();
    const [amount, setAmount] = useState("");
    const [balance, setBalance] = useState(BigInt(0))
    const [isConning, setIsConning] = useState(false)
    const [connectSuccess, setConnectSuccess] = useState(false)
    const [isTxing, setIsTxing] = useState(false)
    const [trxId, setTrxId] = useState()
    const [mappedAccount, setMappedAccount] = useState()

    const onChangeRpc = (e) => {
        setRpcEndpoint(e.target.value);
    }
    const onChangeAddress = (e) => {
        setToAddress(e.target.value);
    }
    const onChangeAmount = (e) => {
        setAmount(e.target.value);
    }
    async function conn() {
        if (!rpcEndpoint) {
            return alert('Endpoint url is empty.')
        }
        setIsConning(true);
        api = await ApiPromise.create({
            provider: new WsProvider(rpcEndpoint),
            noInitWarn: true,
        });
        walletClient = createWalletClient({ chain: mainnet, transport: custom(window.ethereum) })
        const [address] = await walletClient.requestAddresses();
        console.log({ address })
        const SS58Prefix = (api.consts?.system?.ss58Prefix).toNumber();
        let ma = await getMappingAccount(api, walletClient, { address }, { SS58Prefix });
        setMappedAccount(ma);
        sub(ma.substrateAddress);
        setIsConning(false);
        setConnectSuccess(true);
        showTips("Connect success!");
    }
    async function transferToAddress() {
        try {
            if (!amount || !toAddress) {
                return;
            }
            let data = {
                amount: parseInt(amount),
                address: toAddress
            };
            if (!api) {
                await conn();
            }
            setIsTxing(true)
            setTrxId('')
            const result = await signAndSendEvm(
                api.tx.balances.transferAllowDeath(data.address, BigInt(data.amount) * BigInt(1e18)),
                api,
                walletClient,
                mappedAccount, []
            )
            const trId = result.status.asInBlock.toHex()
            setTrxId(trId)
            showTips("Transfer success!");
        } finally {
            setIsTxing(false)
        }
    }
    async function sub(addr) {
        await api.query.system.account(
            addr,
            (info) => setBalance(formatAmount(info.data.free.toBigInt())))
    }
    const showTips = (txt, ms = 5000) => {
        setOkTipsTxt(txt);
        setTimeout(function () {
            setOkTipsTxt("");
        }, ms);
    }
    const onCopy = (txt) => {
        copy(txt);
        showTips("Copy success!");
    }
    const formatAmount = (txt) => {
        console.log('txt', txt);
        txt = BigInt(txt) / BigInt(1e18);
        return txt;
    }

    return (<div>
        <div className='ok-tips' style={{ top: okTipsTxt ? 0 : "-100px" }}>{okTipsTxt}</div>
        <h1>CESS Transfer Tool</h1>
        <div className='content'>
            <div className='box'>
                <input
                    type="text"
                    name="address"
                    className="input"
                    placeholder="Endpoint RPC URL"
                    value={rpcEndpoint}
                    onChange={onChangeRpc}
                />
                {
                    isConning ?
                        <button className='btn btn-disable'>Connecting</button> :
                        connectSuccess ? <span className='success'>Connect Success!</span> : <button onClick={conn} className='btn'>Connect Wallet</button>
                }
            </div>
            <div className='box'>
                <input
                    type="text"
                    name="address"
                    className="input"
                    placeholder="To Address(CESS)"
                    value={toAddress}
                    onChange={onChangeAddress}
                />
                <input
                    type="text"
                    name="address"
                    className="input"
                    placeholder="Transfer Amount"
                    value={amount}
                    onChange={onChangeAmount}
                />
                {
                    isTxing ?
                        <button className='btn btn-disable'>Loading</button> :
                        <button onClick={transferToAddress} className='btn'>Transfer</button>
                }
            </div>
            <div className='box'>
                <div className='line'>
                    <div className='left'>
                        EvmAddress:
                    </div>
                    <div className='right' onClick={() => onCopy(mappedAccount?.evmAddress)}>
                        {mappedAccount?.evmAddress}
                    </div>
                </div>
                <div className='line'>
                    <div className='left'>
                        SubstrateAddress:
                    </div>
                    <div className='right' onClick={() => onCopy(mappedAccount?.substrateAddress)}>
                        {mappedAccount?.substrateAddress}
                    </div>
                </div>
                {
                    trxId ? <div className='line'>
                        <div className='left'>
                            Transfer Hash:
                        </div>
                        <div className='right' onClick={() => onCopy(trxId)}>
                            {trxId}
                        </div>
                    </div> : ""
                }
                <div className='line'>
                    <div className='left'>
                        Balance:
                    </div>
                    <div className='right' onClick={() => onCopy(balance?.toString())}>
                        {balance?.toString()}
                    </div>
                </div>
            </div>
        </div>
    </div>)
}